package edu.csu.smartpark.controller;

import com.alibaba.fastjson.JSONObject;
import edu.csu.smartpark.model.DO.ParkSpaceDO;
import edu.csu.smartpark.model.DTO.ParkSpaceDTO;
import edu.csu.smartpark.model.VO.PageVO;
import edu.csu.smartpark.model.VO.ParkSpaceVO;
import edu.csu.smartpark.model.common.BusinessException;
import edu.csu.smartpark.model.common.MsgEntity;
import edu.csu.smartpark.service.ParkSpaceService;
import edu.csu.smartpark.util.Constants;
import edu.csu.smartpark.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

@RestController
@Slf4j
@RequestMapping("/space")
@RequiresRoles(value = Constants.ParkAdministrator)
public class ParkSpaceController {
    @Autowired
    private ParkSpaceService parkSpaceService;

    @PostMapping("/add")
    public MsgEntity createParkSpace(@RequestBody  @Validated ParkSpaceDTO parkSpaceDTO) throws BusinessException {
        // 参数校验
        if (parkSpaceDTO == null){
            return new MsgEntity("success", MsgEntity.SUCCESS, "parameter bind error");
        }
        if (parkSpaceDTO.getTypeCode().equals(Constants.house)){
            if (parkSpaceDTO.getRoomCapacity() == null){
                return new MsgEntity("success", MsgEntity.SUCCESS, "room capacity can not be empty");
            }
            if (parkSpaceDTO.getRoomSize() == null){
                return new MsgEntity("success", MsgEntity.SUCCESS, "room size can not be empty");
            }
        }
        if(parkSpaceDTO.getTypeCode().equals(Constants.parkSpaceChannel)){
            if (parkSpaceDTO.getDirection() == null){
                return new MsgEntity("success", MsgEntity.SUCCESS, "park channel direction can not be empty");
            }
        }
        if (parkSpaceDTO.getTypeCode().equals(Constants.parkingArea)){
            if (parkSpaceDTO.getTollStandardId() == null){
                return new MsgEntity("success", MsgEntity.SUCCESS, "park area toll standard id can not be empty");
            }
        }
        ParkSpaceDO parkSpaceDO = new ParkSpaceDO();
        BeanUtils.copyProperties(parkSpaceDTO, parkSpaceDO);
        String spaceId = parkSpaceService.createParkSpace(parkSpaceDO);
        return new MsgEntity("success", MsgEntity.SUCCESS, spaceId);
    }

    @PostMapping("/update")
    public MsgEntity modifyParkSpace(@RequestBody JSONObject params) throws BusinessException {
        String spaceId = params.getString("spaceId");
        String name = params.getString("name");
        Integer direction = (Integer) params.get("direction");
        Integer roomSize = (Integer) params.get("roomSize");
        Integer roomCapacity = (Integer) params.get("roomCapacity");
        String tollStandardId = params.getString("tollStandardId");
        if (spaceId == null || spaceId.equals("")){
            return new MsgEntity("success", MsgEntity.SUCCESS, "space id can not be empty");
        }
        ParkSpaceDO parkSpaceDO = new ParkSpaceDO();
        parkSpaceDO.setSpaceId(spaceId);
        parkSpaceDO.setName(name);
        parkSpaceDO.setDirection(direction);
        parkSpaceDO.setRoomSize(roomSize);
        parkSpaceDO.setTollStandardId(tollStandardId);
        parkSpaceDO.setRoomCapacity(roomCapacity);
        parkSpaceService.updateParkSpace(parkSpaceDO);
        return new MsgEntity("success", MsgEntity.SUCCESS, "update space info success");
    }

    @GetMapping("/delete")
    public MsgEntity removeParkSpace(String spaceId) throws BusinessException{
        if (spaceId == null || spaceId.equals("")){
            return new MsgEntity("fail", MsgEntity.FAIL, "space id can not be empty");
        }
        parkSpaceService.deleteParkSpace(spaceId);
        return new MsgEntity("success", MsgEntity.SUCCESS, "delete space success");
    }

    @PostMapping("/get")
    public MsgEntity getSpaceInfos(@RequestBody JSONObject params) throws BusinessException{
        List<String> spaceIds = (List<String>) params.get("spaceIds");
        if (spaceIds == null || spaceIds.size() == 0){
            return new MsgEntity("fail", MsgEntity.FAIL, "space ids can not be empty");
        }
        Map<String, ParkSpaceDO> spaceInfos =  parkSpaceService.getSpaceInfos(spaceIds);
        Map<String, ParkSpaceVO> res = new HashMap<>();
        for (Map.Entry<String, ParkSpaceDO> entry : spaceInfos.entrySet()){
            ParkSpaceVO parkSpaceVO = new ParkSpaceVO();
            BeanUtils.copyProperties(entry.getValue(), parkSpaceVO);
            res.put(entry.getKey(), parkSpaceVO);
        }
        return new MsgEntity("success", MsgEntity.SUCCESS, res);
    }

    @PostMapping("/sub/query")
    public MsgEntity getSubSpace(@RequestBody JSONObject params) throws BusinessException{
        String spaceId = params.getString("spaceId");
        int pageNum = (int)params.getOrDefault("pageNum", 1);
        int pageSize = (int)params.getOrDefault("pageSize", 10);
        String typeCode = params.getString("typeCode");
        if (StringUtil.isEmpty(typeCode)){
            return new MsgEntity("fail", MsgEntity.FAIL, "typeCode can not be empty");
        }
        PageVO<ParkSpaceDO> subSpacePage = parkSpaceService.getSubSpaceList(pageNum, pageSize, spaceId, typeCode);
        PageVO<ParkSpaceVO> res = new PageVO<>();
        List<ParkSpaceDO> subSpaceDOs = subSpacePage.getRecords();
        List<ParkSpaceVO> subSpaceVOs = new LinkedList<>();
        for (ParkSpaceDO parkSpaceDO : subSpaceDOs){
            ParkSpaceVO parkSpaceVO = new ParkSpaceVO();
            BeanUtils.copyProperties(parkSpaceDO, parkSpaceVO);
            subSpaceVOs.add(parkSpaceVO);
        }
        BeanUtils.copyProperties(subSpacePage, res);
        res.setRecords(subSpaceVOs);
        return new MsgEntity("success", MsgEntity.SUCCESS, res);
    }

}
